package org.xielei.stream;


import com.alibaba.fastjson.JSON;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import org.apache.commons.lang3.StringUtils;
import org.junit.Test;
import org.springframework.util.CollectionUtils;
import org.xielei.util.JsonUtil;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.TreeSet;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author xielei
 */
public class CollectTest {

    @Test
    public void toMapTest() {
        List<ConsultDoctorVo> doctors = getList();
        Map<String, Boolean> collect = doctors.stream()
                .collect(Collectors.toMap(ConsultDoctorVo::getDeptCode, d -> d.deptCode != null, (o1, o2) -> o1));
        System.out.println(collect);
    }

    @Test
    public void optionalOfTest() {
        List<ConsultDoctorVo> doctors = getList();

        Map<String, List<ConsultDoctorVo>> stringListMap = doctors.stream()
                .collect(Collectors.groupingBy(ConsultDoctorVo::getDocCode));
        System.out.println(stringListMap.toString());

        List<ConsultDoctorVo> list = Optional.of(stringListMap)
                .filter(stringListMap1 -> !stringListMap1.isEmpty())
                .map(map -> map.get("1001"))
                .get();
        System.out.println(list);

        boolean b1 = list.stream()
                .anyMatch(shareOrderVO -> "2001".equals(shareOrderVO.getDeptCode()));
        System.out.println(b1);

        Boolean s = Optional.of(stringListMap)
                .filter(stringListMap1 -> !stringListMap1.isEmpty())
                .map(map -> map.get("1001"))
                .map(orderVoList -> orderVoList.stream()
                        .anyMatch(shareOrderVO -> "2001".equals(shareOrderVO.getDeptCode())))
                .orElse(false);
        System.out.println(s);
        String b = s ? "已完成" : "待付款";
        System.out.println(b);

    }

    @Test
    public void jsonTest() {
        List<ConsultDoctorVo> doctors = getList();
        String jsonString = JSON.toJSONString(doctors);
        System.out.println("json >>>>>>>>>>>>" + jsonString);
        Map<String, Object> map = new HashMap<>();
        map.put("vo", jsonString);
        System.out.println("map >>>>>>>>>>>>" + JSON.toJSONString(map));
    }

    @Test
    public void joiningTest() {
        List<String> itemNos = Arrays.asList("aaa", "abc", "cxa", "ccc", "bdc", "abc");
        String buffer = itemNos.stream()
                .sorted()
                .collect(Collectors.joining("-",
                        new StringBuffer().append("order").append("shopId").append("-")
                                .append("hosID").append("-")
                                .append("userId").append("-"),
                        ""));
        System.out.println(buffer);
    }

    @Test
    public void collectingAndThen() {
        List<ConsultDoctorVo> doctors = getList();

        doctors = doctors.stream()
                .collect(
                        Collectors.collectingAndThen(
                                Collectors.toCollection(
                                        () -> new TreeSet<>(Comparator.comparing(
                                                consultDoctorVo -> consultDoctorVo.getDocWorkGroupFlag() + consultDoctorVo.getDocCode()
                                        ))
                                ), ArrayList::new
                        )
                );
        System.out.println(doctors);

        Map<String, List<ConsultDoctorVo>> maps = doctors.stream()
                .collect(Collectors.groupingBy(ConsultDoctorVo::getDocCode));

        String titleDn = Optional.of(maps.get("1003"))
                .filter(map -> !CollectionUtils.isEmpty(map))
                .map(members -> members.stream()
                        .map(ConsultDoctorVo::getTitleDn)
                        .collect(Collectors.collectingAndThen(
                                Collectors.joining(","),
                                deptName -> Stream.of(deptName.split(","))
                                        .distinct()
                                        .collect(Collectors.joining(",")))
                        ))
                .orElse("暂无");
        System.out.println(titleDn);
    }

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    static class ConsultDoctorVo {

        private String docCode;

        private String deptCode;

        private String titleDn;

        private Boolean recommend;

        private String docWorkGroupFlag;
    }


    @Test
    public void nullCollectionTest() {
        List<Integer> logList = null;

        List<String> strings = Optional.ofNullable(logList)
                .orElseGet(ArrayList::new)
                .stream()
                .map(Objects::nonNull)
                .map(Object::toString)
                .collect(Collectors.toList());
        System.out.println(strings.toString());
    }

    @Test
    public void allMatchTest() {
        List<ConsultDoctorVo> doctorList = getList();
        Boolean aBoolean = Optional.of(doctorList)
                .filter(doctors -> !CollectionUtils.isEmpty(doctors))
                .map(doctors -> doctors.stream()
                        .allMatch(doctorVo -> "1001".equals(doctorVo.getDocCode())))
                .orElse(false);


        System.out.println(aBoolean);

        boolean allMatch = doctorList.stream()
                .allMatch(doctorVo -> "1001".equals(doctorVo.getDocCode()));
        System.out.println(allMatch);
    }

    @Test
    public void anyMatchTest() {
        List<ConsultDoctorVo> list = this.getList();
        boolean anyMatch = list.stream()
                .filter(consultDoctorVo -> consultDoctorVo.getRecommend())
                .anyMatch(consultDoctorVo -> consultDoctorVo.getDocWorkGroupFlag().equals("1"));
        System.out.println(anyMatch);
    }

    @Test
    public void joinTest() {
        Map<String, Object> params = new HashMap(){{
            put("tom", null);
            put("jerry", "sart");
            put("john", null);
        }};
        System.out.println(params);

        List<String> sqlParams = params.keySet().stream()
//                .filter(key -> StringUtils.isNotBlank((String)params.get(key)))
                .map(key -> "\"" + key + "\"" + "=>" + "'" + params.get(key) + "'")
                .collect(Collectors.toList());
        System.out.println(sqlParams);
    }

    private List<ConsultDoctorVo> getList() {
        List<ConsultDoctorVo> doctors = new ArrayList<>();
        doctors.add(new ConsultDoctorVo("1001", "2001", "eye,norse", true, "1"));
        doctors.add(new ConsultDoctorVo("1002", "2002", "born", true, "0"));
        doctors.add(new ConsultDoctorVo("1003", "2003", "head,hand", true, "1"));
        doctors.add(new ConsultDoctorVo("1003", "2001", "hand", true, "1"));
        doctors.add(new ConsultDoctorVo("1002", "2001", "hand,arm", true, "0"));
        doctors.add(new ConsultDoctorVo("1001", "2002", "month", true, "1"));
        return doctors;
    }


    @Setter
    @Getter
    @ToString
    @NoArgsConstructor
    @AllArgsConstructor
    public static class TodoVO {

        private List<ItemVO> itemVOList;
    }

    @Setter
    @Getter
    @ToString
    @NoArgsConstructor
    @AllArgsConstructor
    public static class ItemVO {

        private String name;

        private String execDeptName;

        private String spec;

        private String num;

        private String unit;

        public ItemVO(String content, String num) {
            this.name = content;
            this.num = num;
        }
    }
}